#include "./Graph/Graph.h"
#include "./Graph/Vertex.h"
#include "./Graph/Edge.h"
#include <algorithm>
#include <iostream>

CGraph::CGraph()
{

}

CGraph::~CGraph()
{
	m_setVertex.clear();
	m_setEdge.clear();
}

/*	
	Vertex functions.
*/

struct _FindVertex
{
	_FindVertex(string str):m_str(str){}

	bool operator()(const CVertex& vertex)
	{
		return (m_str == vertex.GetID());
	}
private:
	string m_str;
};

int CGraph::InsertVertex(char* szName)
{
	if (FAILED == FindVertex(szName))
	{
		CVertex vertex(szName);
		m_setVertex.insert(vertex);
		return SUCCEED;
	}	
	return FAILED;
}

int CGraph::InsertVertex(CVertex vertex)
{
	if (FAILED == FindVertex(vertex))
	{
		m_setVertex.insert(vertex);
		return SUCCEED;
	}	
	return FAILED;
}

int CGraph::RemoveVertex(char* szVertexName)
{
	if (SUCCEED == FindVertex(szVertexName))
	{
		CVertex vertex(szVertexName);
		m_setVertex.erase(vertex);
		return SUCCEED;
	}
	return FAILED;
}

int CGraph::RemoveVertex(CVertex vertex)
{
	if (SUCCEED == FindVertex(vertex))
	{		
		m_setVertex.erase(vertex);
		return SUCCEED;
	}
	return FAILED;
}

int CGraph::FindVertex(char* szVertexName)
{
	CVertex vertex(szVertexName);
	return (m_setVertex.count(vertex) > 0 ? SUCCEED : FAILED);
}

int CGraph::FindVertex(CVertex vertex)
{
	return FindVertex(const_cast<char*>(vertex.GetID().c_str()));
}

void CGraph::PrintAllVertex()
{
	VertexSet::const_iterator iter = m_setVertex.begin();
	for (; iter != m_setVertex.end(); ++iter)
	{
		std::cout << iter->GetID() << " ";
	}
	std::cout << std::endl;
}

/*
	Edge functions.
*/

int CGraph::InsertEdge(char* szBeginVertexName, char* szEndVertexName)
{
	if (FAILED == FindEdge(szBeginVertexName, szEndVertexName))
	{
		if (SUCCEED == FindVertex(szBeginVertexName) && SUCCEED == FindVertex(szEndVertexName))
		{
			CEdge edge(szBeginVertexName, szEndVertexName);
			m_setEdge.insert(edge);
			return SUCCEED;
		}
	}
	return FAILED;
}

int CGraph::InsertEdge(CVertex BeginVertex, CVertex EndVertex)
{
	if (FAILED == FindEdge(BeginVertex, EndVertex))
	{
		if (SUCCEED == FindVertex(BeginVertex) && SUCCEED == FindVertex(EndVertex))
		{
			CEdge edge(BeginVertex, EndVertex);
			m_setEdge.insert(edge);
			return SUCCEED;
		}		
	}
	return FAILED;
}

int CGraph::RemoveEdge(char* szBeginVertexName, char* szEndVertexName)
{
	if (SUCCEED == FindEdge(szBeginVertexName, szEndVertexName))
	{
		m_setEdge.erase(CEdge(szBeginVertexName, szEndVertexName));
		return SUCCEED;
	}
	return FAILED;
}

int CGraph::RemoveEdge(CVertex BeginVertex, CVertex EndVertex)
{
	if (SUCCEED == FindEdge(BeginVertex, EndVertex))
	{
		m_setEdge.erase(CEdge(BeginVertex, EndVertex));
		return SUCCEED;
	}
	return FAILED;
}

int CGraph::FindEdge(char* szBeginVertexName, char* szEndVertexName)
{
	CEdge edge(szBeginVertexName, szEndVertexName);
	return (m_setEdge.count(edge) > 0 ? SUCCEED : FAILED); 
}

int CGraph::FindEdge(CVertex BeginVertex, CVertex EndVertex)
{
	CEdge edge(BeginVertex, EndVertex);
	return (m_setEdge.count(edge) > 0 ? SUCCEED : FAILED); 
}

void CGraph::PrintAllEdge()
{
	EdgeSet::const_iterator iter = m_setEdge.begin();
	for (; iter != m_setEdge.end(); ++iter)
	{
		std::cout << iter->GetID() << " ";
	}
	std::cout << std::endl;
}
